using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Xml;
using System.Xml.Linq;
using System.Linq;
namespace RStein.Posterous.API
{
    internal class PosterousResponseBuilder : IResponseBuilder
    {
        #region Constants

        #endregion Constants



        public T ParseResponse<T>(WebResponse response, Func<Stream, T> parser)
        {
            var httpResponse = response as HttpWebResponse;

            if (httpResponse == null)
            {
                throw new ArgumentException(GlobalConstants.REQUEST_BUILDER_HTTP_PROTOCOL_EX, "response");
            }

            if (httpResponse.StatusCode != HttpStatusCode.OK)
            {
                throw new PosterousException(GlobalConstants.INVALID_RESPONSE_EX);
            }

            try
            {
                using (MemoryStream copyStream = new MemoryStream())
                {

                    using (response)
                    {

                        using (var stream = response.GetResponseStream())
                        {
                            stream.CopyToStream(copyStream);
                        }
                    }

                    copyStream.Position = 0;
                    checkServerError(copyStream);
                    copyStream.Position = 0;
                    return parser(copyStream);
                }
                
            }

            catch (Exception e)
            {

                throw new PosterousException(GlobalConstants.INVALID_RESPONSE_EX, e);
            }

        }


        private void checkServerError(Stream stream)
        {
            XmlReader reader = XmlReader.Create(stream);
            XElement root = XElement.Load(reader);
            string val = root.Attributes(GlobalConstants.XML_STAT_ATTRIBUTE).Single().Value;
            if (val == GlobalConstants.RESPONSE_OK_STATUS)
            {
                return;
            }

            Debug.Assert(val == GlobalConstants.RESPONSE_FAIL_STATUS);
            var errElement = root.Elements(GlobalConstants.XML_ERR_ELEMENT).Single();
            string errorCode = errElement.Attribute(GlobalConstants.XML_CODE_ATTRIBUTE).Value;
            string errorMessage = errElement.Attribute(GlobalConstants.XML_MSG_ATTRIBUTE).Value;

            throw new PosterousException(GlobalConstants.INVALID_RESPONSE_EX)
                      {
                          ErrorCode = errorCode,
                          ErrorDetail = errorMessage

                      };

        }

    }

}

        